<template>
  <div>

    <el-row>
      <el-col :span="1">
        <el-button type="primary" @click="dialogVisible = true" icon="el-icon-plus">新增</el-button>
      </el-col>
    </el-row>

    <!-- tree 表格 -->
    <zk-table
      ref="table"
      :data="menuList"
      :columns="columns" border
      :selection-type="false"
      :expand-type="false"
    >
      <!-- 类型插槽 -->
      <template slot="typeTemplate" slot-scope="scope">
        <el-tag size="small" v-if="scope.row.type === 2">{{scope.row.typeValue}}</el-tag>
        <el-tag type="warning" size="small" v-else-if="scope.row.type === 3">{{scope.row.typeValue}}</el-tag>
        <!--        <el-tag type="success" size="small" v-else-if="scope.row.level === 3">{{scope.row.typeValue}}</el-tag>-->
      </template>
      <!-- 级别插槽 -->
      <template slot="levelTemplate" slot-scope="scope">
        <el-tag size="small" v-if="scope.row.level === 1">一级</el-tag>
        <el-tag type="warning" size="small" v-else-if="scope.row.level === 2">二级</el-tag>
        <el-tag type="success" size="small" v-else-if="scope.row.level === 3">三级</el-tag>
      </template>
      <!-- 状态插槽 -->
      <template slot="statusTemplate" slot-scope="scope">
        <el-switch v-model="scope.row.statusBoolean" @change="statusChange(scope.row.id, scope.row.statusBoolean)"></el-switch>
      </template>
      <!-- 操作插槽 -->
      <template slot="optTemplate" slot-scope="scope">
        <el-button type="text" icon="el-icon-edit" size="mini" @click="get(scope.row.id)">编辑</el-button>
        <el-button type="text" icon="el-icon-delete" size="mini" @click="remove(scope.row.id)">删除</el-button>
      </template>
    </zk-table>

    <!-- 模态 -->
    <el-dialog title="菜单" :visible.sync="dialogVisible" width="30%" @close="closeDialog">
      <!-- 主体 -->
      <el-form ref="itemRef" :model="item" :rules="itemRules" label-width="80px">
        <el-form-item label="名称" prop="name">
          <el-input v-model="item.name" clearable></el-input>
        </el-form-item>
        <el-form-item label="地址" prop="url">
          <el-input v-model="item.url" clearable></el-input>
        </el-form-item>
        <el-form-item label="类型" prop="type">
          <el-radio-group v-model="item.type">
            <el-radio v-for="item in menuTypeList" :label="item.type" :key='item.type'>{{item.typeValue}}</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="上级菜单" prop="parent">
          <el-cascader v-model="item.tmpParentArray" :options="menuList" expandTrigger="hover" :checkStrictly="true"
                       :props="{ value: 'id', label: 'name', checkStrictly: true }"
                       @change="menuCascaderChange" @blur="menuCascaderChange"
                       clearable placeholder="根目录"></el-cascader>
        </el-form-item>
        <el-form-item label="权限编码" prop="code">
          <el-input v-model="item.code" clearable></el-input>
        </el-form-item>
        <el-form-item label="序号" prop="num">
          <el-input-number v-model="item.num" :min="0" :max="100" :step="1" step-strictly></el-input-number>
        </el-form-item>
      </el-form>
      <!-- 底部按钮 -->
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="postData">确 定</el-button>
      </span>
    </el-dialog>

  </div>
</template>

<script>

export default {
  components: {},
  data () {
    // 菜单-上级菜单选择，规则校验
    var checkMenuParent = (rule, value, callback) => {
      console.log('parent: ' + this.item.parent + ', this.item.id: ' + this.item.id)
      if (this.item.id && Number(this.item.parent) === Number(this.item.id)) {
        callback(new Error('菜单上级节点不能为自己'))
      } else if ((value === '' || value === 0) && this.item.type === 3) {
        callback(new Error('权限不能位于根目录下'))
      } else {
        callback()
      }
    }
    var checkCode = (rule, value, callback) => {
      // console.log('parent: ' + this.item.parent + ', this.item.id: ' + this.item.id)
      if (this.item.type === 3 && !value) {
        callback(new Error('请输入权限'))
      } else {
        callback()
      }
    }
    return {
      // 所有菜单
      menuList: [],
      // 菜单类型
      menuTypeList: [],
      // tree 菜单参数
      columns: [
        {
          label: '名称',
          prop: 'name'
        },
        {
          label: '地址',
          prop: 'url',
          minWidth: '130px'
        },
        {
          label: '类型',
          type: 'template',
          template: 'typeTemplate'
        },
        {
          label: '权限编码',
          prop: 'code'
        },
        {
          label: '顺序',
          prop: 'num'
        },
        {
          label: '状态',
          type: 'template',
          template: 'statusTemplate'
        },
        {
          label: '操作',
          type: 'template',
          template: 'optTemplate'
        }
      ],
      // 模态显示
      dialogVisible: false,
      // 单个数据
      item: {
        id: '',
        name: '',
        code: '',
        parent: '',
        type: '',
        icon: '',
        url: '',
        num: '',
        status: '',
        tmpParentArray: ''
      },
      // 模态校验
      itemRules: {
        name: [
          { required: true, message: '请输入名称', trigger: 'blur' },
          { max: 10, message: '名称过长', trigger: 'blur' }
        ],
        url: [
          { max: 100, message: '地址最长 100 个字符', trigger: 'blur' }
        ],
        type: [
          { required: true, message: '请选择类型', trigger: 'change' }
        ],
        parent: [
          { validator: checkMenuParent, trigger: 'change' }
        ],
        code: [
          { max: 30, message: '权限编码最长 30 个字符', trigger: 'blur' },
          { validator: checkCode, trigger: 'blur' }
        ],
        num: [
          { required: true, message: '请输入序号', trigger: 'blur' }
        ]
      }
    }
  },
  created () {
    this.listAll()
    this.listMenuType()
  },
  methods: {
    // 显示所有菜单
    async listAll () {
      const { data } = await this.$axios.post('/menu/listAll')
      this.menuList = data.data
    },
    // 显示所有菜单类型
    async listMenuType () {
      const { data } = await this.$axios.post('/menu/listType')
      this.menuTypeList = data.data
    },
    // 注意，switch 回调值为变更后的值
    async statusChange (id, statusBool) {
      console.log('id: ' + id + ', status: ' + statusBool)
      let requestUrl
      if (statusBool) {
        requestUrl = '/menu/unlock'
      } else {
        requestUrl = '/menu/lock'
      }
      const { data } = await this.$axios.post(requestUrl, { menuId: id })
      this.$message.success(data.msg)
    },
    // 模态关闭
    closeDialog () {
      // 重置校验
      this.$refs.itemRef.resetFields()
    },
    // 详情
    async get (id) {
      const { data } = await this.$axios.post('/menu/get', { id: id })
      this.item = data.data
      this.item.tmpParentArray = data.data.parent
      this.dialogVisible = true
    },
    // 上级菜单选择，触发事件
    menuCascaderChange () {
      // 组件返回的是一个数组，只获取最后一个；若空数组，填充根节点 0
      // console.log('menuCascaderChange tmpParentArray: ' + this.item.tmpParentArray)
      if (this.item.tmpParentArray && this.item.tmpParentArray.length > 0) {
        this.item.parent = this.item.tmpParentArray[this.item.tmpParentArray.length - 1]
      } else {
        this.item.parent = 0
      }
      // console.log('menuCascaderChange parent: ' + this.item.parent)
    },
    // 提交修改
    async postData () {
      this.$refs.itemRef.validate(async valid => {
        if (valid) {
          let requestUrl
          if (this.item.id) {
            requestUrl = '/menu/update'
          } else {
            requestUrl = '/menu/save'
          }
          const { data } = await this.$axios.post(requestUrl, this.item)
          // 后续操作：弹窗、关模态、刷新分页、清空表单数据
          this.$message.success(data.msg)
          this.dialogVisible = false
          this.listAll()
          this.closeDialog()
        }
      })
    },
    // 删除
    async remove (id) {
      const confirmResult = await this.$confirm('将删除该菜单, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).catch(err => err)
      if (confirmResult === 'confirm') {
        const { data } = await this.$axios.post('/menu/delete', { id: id })
        this.$message.success(data.msg)
        this.listAll()
      }
    }
  }
}
</script>

<style scoped>

</style>
